import 'package:flutter/material.dart';

class TabAnimationBar extends StatefulWidget {

  final Color backgroundColor;            // tabbarView的背景颜色
  final List<Widget> children;
  final List<Widget> selectedChildren;
  int index;
  final Function(int selected) onPress;
  final Color dividerColor;               // 分割线颜色
  final double circleOffset;              // 圆突出的范围10 - 30
  final double circleRadiuOffset;         // 圆大小的偏移
  final Duration animateDuration; 
  final Curve curve; 

  TabAnimationBar({
      Key key, 
      @required this.backgroundColor, 
      @required this.children, 
      @required this.onPress, 
      @required this.selectedChildren,
      this.dividerColor = Colors.black12,
      this.index = 0,
      this.circleOffset = 0.3,
      this.circleRadiuOffset = 0,
      this.animateDuration = const Duration(milliseconds: 150),
      this.curve = Curves.bounceOut
    })
     : super(key: key);

  @override
  _TabAnimationPageState createState() => _TabAnimationPageState();
}

class _TabAnimationPageState extends State<TabAnimationBar> with SingleTickerProviderStateMixin {

  AnimationController _controller;
  Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(vsync: this, duration: widget.animateDuration);
    CurvedAnimation _cure = CurvedAnimation(curve: widget.curve, parent: _controller);
    _animation = Tween<double>(begin: 0, end: widget.circleOffset).animate(_cure)
    ..addListener((){
      setState(() {
        
      });
    });
    _controller.forward();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  _onIconPressed(int index) async {
    // 首先重置弧度的位置
    if(_controller.status == AnimationStatus.completed){
      await _controller.reverse();
    } 
    setState(() {
      widget.index = index;
    });
    widget.onPress(index);
    _controller.forward();
  }

  Widget _createFlex(Widget child) {
    final size = MediaQuery.of(context).size;
    final margin = MediaQuery.of(context).padding;
    return Container(
      width: size.width / widget.children.length,
      child: child,
    );
  }

  @override
  Widget build(BuildContext context) {
    final size = MediaQuery.of(context).size;
    final margin = MediaQuery.of(context).padding;
    final height = 50 + margin.bottom;
    return Container(
      height: height,
      alignment: Alignment.topCenter,
      decoration: BoxDecoration(
        // color: Colors.transparent,
        color: Colors.red,
        boxShadow: [
          BoxShadow(blurRadius: 10.0, color: Colors.black26)
        ]
      ),
      child: Stack(
        overflow: Overflow.visible,
        children: [
          CustomPaint(
          size: Size(size.width, height),
          painter: WaveTabbar(
            index: widget.index,
            valY: _animation.value,
            color: widget.backgroundColor,
            circleRadiusOffset: widget.circleRadiuOffset,
            childrenCount: widget.children.length,
            dividerColor: widget.dividerColor
          ),),
          Container(
            height: height,
            padding: EdgeInsets.only(bottom: margin.bottom / 3),
            color: widget.backgroundColor,
            alignment: Alignment.topCenter,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: List.generate(widget.children.length, (index) => GestureDetector(
                child: widget.index == index ? _createFlex(widget.selectedChildren[index]) : _createFlex(widget.children[index]),
                onTap:() => _onIconPressed(index),
              )),
            ),
          ),
        ],
      ),
    );
  }
}

class WaveTabbar extends CustomPainter {
  final int index;
  final double valY;
  final Color color;
  final int childrenCount;
  final Color dividerColor;
  final double circleRadiusOffset;

  WaveTabbar({
    this.index, 
    this.valY, 
    this.color, 
    this.childrenCount,
    this.dividerColor = Colors.black12,
    this.circleRadiusOffset = 0
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
    ..color = color
    ;
    

    final double circleHeight = size.height + circleRadiusOffset;
    final double circleWiddth = circleHeight * 1.3;
    final circleY = -valY * circleHeight;
    // 计算间距
    double distance = (size.width / childrenCount - circleWiddth) / 2.0;

    // final paint2 = Paint()
    // ..color = dividerColor
    // ..strokeWidth = 0.5
    // ..style = PaintingStyle.stroke
    // ;
    // canvas.drawLine(Offset(0, 0), Offset(size.width, 0), paint2);

    // 绘制圆
    Path path = Path()
    ..addOval(Rect.fromLTWH((size.width) / childrenCount * index + distance, circleY, circleWiddth, circleHeight));
    Shadow shadow = BoxShadow(blurRadius: 10.0, color: Colors.black26);
    var paint3 = shadow.toPaint();
    canvas.drawPath(path, paint3);
    canvas.drawPath(path, paint);
    
    // // 绘制圆的边框
    // double circleRadiu = circleWidth / 2.0 + 0.5;
    // canvas.drawCircle(Offset((size.width) / childrenCount * index + distance + circleRadiu , circleY + circleRadiu), circleRadiu, paint2);
  }

  @override
  bool shouldRepaint(WaveTabbar oldDelegate) {
    return true;
  }

}